2 Dado un string $s$, encontrar el número total de substrings distintas.
4 \subsection{Resolución
}
5 Para resolver este problema, primero notamos que todo
\textit{substring
} de la cadena $s$
6 es prefijo de algún sufijo de $s$ (la vuelta también es cierta: todo prefijo de algún
7 sufijo es
\textit{substring
} de $s$). A partir de esto, vemos que para contar la cantidad
8 de
\textit{substrings
} distintos se puede contar la cantidad de prefijos distintos que
9 tienen todos los sufijos.
11 Las subcadenas que estén repetidas deben ser necesariamente prefijos de más de un sufijo.
12 Esto se debe a que si cada subcadena está definida por un par de índices válidos $i$, $j$
13 dentro de la cadena (con $i < j$), una aparición repetida de la misma subcadena involucra
14 que dicha subcadena ocurra en
2 lugares distintos dentro de la cadena, lo que por lo tanto define
15 una posición de inicio $i$ distinta. Para cada uno de estos $i$ existe un sufijo correspondiente
16 tomando $j=longitud(cadena)$.
18 Por lo tanto, para contabilizar rapidamente las subcadenas distintas, resulta muy útil
19 tener los sufijos ordenados lexicográficamente. Si una subcadena aparece más de una vez
20 en la cadena, cada aparición es prefijo de un sufijo de la cadena. Como todos estos
21 sufijos comienzan por la misma cadena, se encontrarán agrupados en el
\textit{suffix
22 array
} ordenado de la misma.
24 Si consideramos los dos sufijos en las posiciones $i$ y $i+
1$ del
\textit{suffix array
},
25 vemos que todas las cadenas repetidas que introduce este último son tantas como el largo
26 del máximo prefijo común entre estos dos sufijos. Esto resulta del hecho de que toda cadena
27 repetida es un prefijo, y de que hay tantos subprefijos idénticos posibles como la longitud del
28 prefijo repetido máximo. Además, no es necesario mirar ningún prefijo anterior al $i$, ya que
29 si el sufijo $i+
1$ tuviera un prefijo compartido más largo con algún otro sufijo que con el $i$,
30 este tercer sufijo se encontraría posicionado en la posición $i$ (ya que sería lexicográficamente
31 más próximo al sufijo $i+
1$).
34 En base a esto, para resolver el ejercicio construimos el
\textit{suffix array
}, y a continuación
35 la tabla asociada del
{\sc{lcp
}}\footnote{No hace falta computar la tabla del
{\sc{lcp
}}, puesto
36 que es suficiente con ir haciendo la suma agregada de los valores, ahorrándose así espacio en memoria
} que
37 se utiliza para contar las subcadenas.
39 La idea es la siguiente: si consideramos el sufijo $j$, de largo $|s|-(j-
1)$, vemos que en
40 principio introduce $|s|-(j-
1)$ prefijos, pero como vimos antes, hay que descontar los prefijos
41 ya contados anteriormente, lo cual corresponde a $lcp
[j
]$.
43 El algoritmo es entonces:
47 \caption{Calcula la cantidad de subcadenas diferentes en una cadena
}
49 \STATE sa, rank = Suffix Array y su permutación inversa
50 \STATE lcp = tabular el LCP usando sa y rank
53 \STATE $substrings += |sa
[i
]| - lcp
[i
]$
60 La construcción del
\textit{suffix array
} se hace con un algoritmo simplificado respecto
61 del visto en clase. Se hacen varias pasadas duplicando cada vez el valor de una variable $K$.
62 El algoritmo ordena cada vez el
\textit{suffix array
} garantizando el orden definitivo si
63 solo se cuentan los primeros $K$ caracteres de cada sufijo. Así, se hacen a lo sumo $
\log_2(n)$
64 pasadas. El costo de cada una es el de realizar el ordenamiento con comparaciones en $O(
1)$,
65 siguiendo la idea detallada en el paper de Karp, Miller y Rosenberg. Utilizando un
66 algoritmo de ordenamiento apropiado se obtiene así un costo total de $O(n
\log^
2(n))$ para
67 la construcción del
\textit{sorted suffix array
}.
69 Para construir el
{\sc{lcp
}} utilizamos el algoritmo de Kasai visto en clase, por lo que la complejidad
70 es $O(n)$ siendo $n$ la cantidad de caracteres del string $s$. La suma de la cantidad de
\textit{substrings
}
71 nuevas de cada sufijo es también $O(n)$.
73 Finalmente dado que el cálculo de la cantidad de
\textit{substrings
} se realiza con una sola
74 pasada sobre el
{\sc{lcp
}}, cuyo tamaño es lineal, concluimos que la complejidad del algoritmo es
75 $O(n
\log^
2 n)$, pero podría mejorarse a $O(n)$ usando un algoritmo más sofisticado para la
76 construcción del
\textit{suffix array
}.
79 En base a esto, la complejidad final es $O(n
\log^
2 n)$.
81 \subsection{Implementación
}
86 \hlstd{}\hlline{\
1\
}\hldir{\#include\ $<$string.h$>$
}\\
87 \hlline{\
2\
}\hlstd{}\hldir{\#include\ $<$cstdio$>$
}\\
88 \hlline{\
3\
}\hlstd{}\hldir{\#include\ $<$algorithm$>$
}\\
89 \hlline{\
4\
}\hlstd{}\\
90 \hlline{\
5\
}\hlkwa{using\
}\hlstd{std
}\hlsym{::
}\hlstd{sort
}\hlsym{;
}\\
91 \hlline{\
6\
}\hlstd{}\hlkwa{using\
}\hlstd{std
}\hlsym{::
}\hlstd{swap
}\hlsym{;
}\\
92 \hlline{\
7\
}\hlstd{}\\
93 \hlline{\
8\
}\hlkwb{static\ char\
}\hlstd{text
}\hlsym{{[}}\hlstd{}\hlnum{50001}\hlstd{}\hlsym{{]};
}\\
94 \hlline{\
9\
}\hlstd{}\hlkwb{static\ unsigned\ int\
}\hlstd{sa
}\hlsym{{[}}\hlstd{}\hlnum{50000}\hlstd{}\hlsym{{]};
}\\
95 \hlline{10\
}\hlstd{}\hlkwb{static\ unsigned\ int\
}\hlstd{rank1
}\hlsym{{[}}\hlstd{}\hlnum{50000}\hlstd{}\hlsym{{]}=\
{}\hlstd{}\hlnum{0}\hlstd{}\hlsym{\
};
}\\
96 \hlline{11\
}\hlstd{}\hlkwb{static\ unsigned\ int\
}\hlstd{rank2
}\hlsym{{[}}\hlstd{}\hlnum{50000}\hlstd{}\hlsym{{]}=\
{}\hlstd{}\hlnum{0}\hlstd{}\hlsym{\
};
}\\
97 \hlline{12\
}\hlstd{}\\
98 \hlline{13\
}\hlkwb{static\ int\
}\hlstd{N
}\hlsym{;
}\\
99 \hlline{14\
}\hlstd{}\hlkwb{static\ long\ long\
}\hlstd{total
}\hlsym{;
}\\
100 \hlline{15\
}\hlstd{}\hlkwb{static\ unsigned\
}\hlstd{cuantos
}\hlsym{;
}\\
101 \hlline{16\
}\hlstd{}\\
102 \hlline{17\
}\hlkwb{bool\
}\hlstd{parar
}\hlsym{;
}\\
103 \hlline{18\
}\hlstd{}\hlkwb{int\
}\hlstd{bucket
}\hlsym{,\
}\hlstd{aux
}\hlsym{,\
}\hlstd{desde
}\hlsym{,\
}\hlstd{actual
}\hlsym{;
}\\
104 \hlline{19\
}\hlstd{}\hlkwb{unsigned\ int
}\hlstd{}\hlsym{{*
}\
}\hlstd{ahora
}\hlsym{;
}\\
105 \hlline{20\
}\hlstd{}\hlkwb{unsigned\ int
}\hlstd{}\hlsym{{*
}\
}\hlstd{proximo
}\hlsym{;
}\\
106 \hlline{21\
}\hlstd{}\\
108 \hlline{23\
}\hlslc{//\ Comparador
}\\
109 \hlline{24\
}\hlstd{}\hlkwb{struct\
}\hlstd{Comparador\
}\hlsym{\
{}\\
110 \hlline{25\
}\hlstd{}\hlstd{\ \ \ \
}\hlstd{}\hlkwb{const\ int\
}\hlstd{K
}\hlsym{;
}\\
111 \hlline{26\
}\hlstd{}\hlstd{\ \ \ \
}\hlstd{}\hlkwb{const\ unsigned\ int
}\hlstd{}\hlsym{{*
}\
}\hlstd{rank
}\hlsym{;
}\\
112 \hlline{27\
}\hlstd{}\hlstd{\ \ \ \
}\hlstd{}\hlkwd{Comparador
}\hlstd{}\hlsym{(
}\hlstd{}\hlkwb{const\ int\
}\hlstd{j
}\hlsym{,
}\hlstd{}\hlkwb{const\ unsigned\ int
}\hlstd{}\hlsym{{*
}\
}\hlstd{vrank
}\hlsym{):\
}\hlstd{}\hlkwd{K
}\hlstd{}\hlsym{(
}\hlstd{j
}\hlsym{),\
}\hlstd{}\hlkwd{rank
}\hlstd{}\hlsym{(
}\hlstd{vrank
}\hlsym{)\ \
{\
};
}\\
113 \hlline{28\
}\hlstd{\\
114 \hlline{29\
}}\hlstd{\ \ \ \
}\hlstd{}\hlkwb{bool\
}\hlstd{}\hlkwc{inline\ operator
}\hlstd{}\hlsym{()(
}\hlstd{}\hlkwb{const\ int\
}\hlstd{i
}\hlsym{,\
}\hlstd{}\hlkwb{const\ int\
}\hlstd{j
}\hlsym{)\
}\hlstd{}\hlkwb{const\
}\hlstd{}\hlsym{\
{}\\
115 \hlline{30\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{return\
}\hlstd{}\hlkwd{clave
}\hlstd{}\hlsym{(
}\hlstd{i
}\hlsym{)\ $<$\
}\hlstd{}\hlkwd{clave
}\hlstd{}\hlsym{(
}\hlstd{j
}\hlsym{);
}\\
116 \hlline{31\
}\hlstd{}\hlstd{\ \ \ \
}\hlstd{}\hlsym{\
}}\\
117 \hlline{32\
}\hlstd{\\
118 \hlline{33\
}}\hlstd{\ \ \ \
}\hlstd{}\hlkwb{int\
}\hlstd{}\hlkwc{inline\
}\hlstd{}\hlkwd{clave
}\hlstd{}\hlsym{(
}\hlstd{}\hlkwb{const\ int\
}\hlstd{i
}\hlsym{)\
}\hlstd{}\hlkwb{const\
}\hlstd{}\hlsym{\
{}\\
119 \hlline{34\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{return\
}\hlstd{}\hlsym{(
}\hlstd{i
}\hlsym{+
}\hlstd{K\
}\hlsym{$<$\
}\hlstd{N\ ?\ rank
}\hlsym{{[}}\hlstd{i
}\hlsym{+
}\hlstd{K
}\hlsym{{]}+
}\hlstd{}\hlnum{1\
}\hlstd{}\hlsym{:\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{);
}\\
120 \hlline{35\
}\hlstd{}\hlstd{\ \ \ \
}\hlstd{}\hlsym{\
}}\\
121 \hlline{36\
}\hlstd{}\hlsym{\
};
}\\
122 \hlline{37\
}\hlstd{}\\
124 \hlline{39\
}\hlkwb{int\
}\hlstd{}\hlkwd{main
}\hlstd{}\hlsym{(
}\hlstd{}\hlkwb{int\
}\hlstd{argc
}\hlsym{,\
}\hlstd{}\hlkwb{const\ char\
}\hlstd{}\hlsym{{*
}}\hlstd{argv
}\hlsym{{[}{]})\ \
{}\\
125 \hlline{40\
}\hlstd{\\
126 \hlline{41\
}}\hlstd{\ \ \ \
}\hlstd{}\hlkwd{scanf
}\hlstd{}\hlsym{(
}\hlstd{}\hlstr{"\%d"
}\hlstd{}\hlsym{,\ \&
}\hlstd{cuantos
}\hlsym{);
}\\
127 \hlline{42\
}\hlstd{\\
128 \hlline{43\
}}\hlstd{\ \ \ \
}\hlstd{}\hlkwa{for\
}\hlstd{}\hlsym{(
}\hlstd{}\hlkwb{int\
}\hlstd{c\
}\hlsym{=\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;\
}\hlstd{c\
}\hlsym{$<$\
}\hlstd{cuantos
}\hlsym{;\
}\hlstd{c
}\hlsym{++)\ \
{}\\
129 \hlline{44\
}\hlstd{\\
130 \hlline{45\
}}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlkwd{scanf
}\hlstd{}\hlsym{(
}\hlstd{}\hlstr{"\%s"
}\hlstd{}\hlsym{,\
}\hlstd{text
}\hlsym{);
}\\
131 \hlline{46\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{N\
}\hlsym{=\
}\hlstd{}\hlkwd{strlen
}\hlstd{}\hlsym{(
}\hlstd{text
}\hlsym{);
}\\
132 \hlline{47\
}\hlstd{\\
133 \hlline{48\
}}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlslc{//\ Suffix\ Array
}\\
134 \hlline{49\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{for\
}\hlstd{}\hlsym{(
}\hlstd{}\hlkwb{int\
}\hlstd{i\
}\hlsym{=\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;\
}\hlstd{i\
}\hlsym{$<$\
}\hlstd{N
}\hlsym{;\
}\hlstd{i
}\hlsym{++)\ \
{}\\
135 \hlline{50\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{sa
}\hlsym{{[}}\hlstd{i
}\hlsym{{]}\ =\
}\hlstd{i
}\hlsym{;
}\\
136 \hlline{51\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{rank1
}\hlsym{{[}}\hlstd{i
}\hlsym{{]}\ =\
}\hlstd{text
}\hlsym{{[}}\hlstd{i
}\hlsym{{]};
}\\
137 \hlline{52\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
138 \hlline{53\
}\hlstd{\\
140 \hlline{55\
}}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlkwd{sort
}\hlstd{}\hlsym{(
}\hlstd{sa
}\hlsym{,\
}\hlstd{sa
}\hlsym{+
}\hlstd{N
}\hlsym{,\
}\hlstd{}\hlkwd{Comparador
}\hlstd{}\hlsym{(
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{,\
}\hlstd{rank1
}\hlsym{));
}\\
141 \hlline{56\
}\hlstd{\\
142 \hlline{57\
}}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{bucket\
}\hlsym{=\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;
}\\
143 \hlline{58\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{rank1
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{}\hlnum{0}\hlstd{}\hlsym{{]}{]}\ =\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;
}\\
144 \hlline{59\
}\hlstd{\\
145 \hlline{60\
}}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{for\
}\hlstd{}\hlsym{(
}\hlstd{}\hlkwb{int\
}\hlstd{t\
}\hlsym{=\
}\hlstd{}\hlnum{1}\hlstd{}\hlsym{;\
}\hlstd{t\
}\hlsym{$<$\
}\hlstd{N
}\hlsym{;\
}\hlstd{t
}\hlsym{++)\ \
{}\\
146 \hlline{61\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{if\
}\hlstd{}\hlsym{(
}\hlstd{text
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{t
}\hlsym{{-
}}\hlstd{}\hlnum{1}\hlstd{}\hlsym{{]}{]}\ ==\
}\hlstd{text
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{t
}\hlsym{{]}{]})\ \
{}\\
147 \hlline{62\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{rank1
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{t
}\hlsym{{]}{]}\ =\
}\hlstd{bucket
}\hlsym{;
}\\
148 \hlline{63\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}\
}\hlstd{}\hlkwa{else\
}\hlstd{}\hlsym{\
{}\\
149 \hlline{64\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{bucket\
}\hlsym{=\
}\hlstd{t
}\hlsym{;
}\\
150 \hlline{65\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{rank1
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{t
}\hlsym{{]}{]}\ =\
}\hlstd{bucket
}\hlsym{;
}\\
151 \hlline{66\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
152 \hlline{67\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
153 \hlline{68\
}\hlstd{\\
154 \hlline{69\
}}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{parar\
}\hlsym{=\
}\hlstd{}\hlkwa{true
}\hlstd{}\hlsym{;
}\\
155 \hlline{70\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{ahora\
}\hlsym{=\
}\hlstd{rank1
}\hlsym{;
}\\
156 \hlline{71\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{proximo\
}\hlsym{=\
}\hlstd{rank2
}\hlsym{;
}\\
157 \hlline{72\
}\hlstd{\\
158 \hlline{73\
}}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{for\
}\hlstd{}\hlsym{(
}\hlstd{}\hlkwb{int\
}\hlstd{K\
}\hlsym{=\
}\hlstd{}\hlnum{1}\hlstd{}\hlsym{;\
}\hlstd{K\
}\hlsym{$<$\
}\hlstd{N
}\hlsym{;\
}\hlstd{K\
}\hlsym{{*
}=\
}\hlstd{}\hlnum{2}\hlstd{}\hlsym{)\ \
{}\\
159 \hlline{74\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{desde\
}\hlsym{=\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;
}\\
160 \hlline{75\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{actual\
}\hlsym{=\
}\hlstd{}\hlnum{1}\hlstd{}\hlsym{;
}\\
161 \hlline{76\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{Comparador\
}\hlkwd{comparador
}\hlstd{}\hlsym{(
}\hlstd{K
}\hlsym{,
}\hlstd{ahora
}\hlsym{);
}\\
162 \hlline{77\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{while\
}\hlstd{}\hlsym{(
}\hlstd{actual\
}\hlsym{$<$\
}\hlstd{N
}\hlsym{)\ \
{}\\
163 \hlline{78\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{while\
}\hlstd{}\hlsym{(
}\hlstd{actual
}\hlsym{$<$\
}\hlstd{N\
}\hlsym{\&\&\
}\hlstd{ahora
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{actual
}\hlsym{{]}{]}\ ==\
}\hlstd{ahora
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{actual
}\hlsym{{-
}}\hlstd{}\hlnum{1}\hlstd{}\hlsym{{]}{]})\ \
{}\\
164 \hlline{79\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{actual
}\hlsym{++;
}\\
165 \hlline{80\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
166 \hlline{81\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{if\
}\hlstd{}\hlsym{(
}\hlstd{actual\
}\hlsym{$>$\
}\hlstd{desde
}\hlsym{+
}\hlstd{}\hlnum{1}\hlstd{}\hlsym{)\ \
{}\\
167 \hlline{82\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwd{sort
}\hlstd{}\hlsym{(
}\hlstd{sa
}\hlsym{+
}\hlstd{desde
}\hlsym{,\
}\hlstd{sa
}\hlsym{+
}\hlstd{actual
}\hlsym{,\
}\hlstd{comparador
}\hlsym{);
}\\
168 \hlline{83\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
169 \hlline{84\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{desde\
}\hlsym{=\
}\hlstd{actual
}\hlsym{;
}\\
170 \hlline{85\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{actual
}\hlsym{++;
}\\
171 \hlline{86\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
172 \hlline{87\
}\hlstd{\\
173 \hlline{88\
}}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{bucket\
}\hlsym{=\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;
}\\
174 \hlline{89\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{proximo
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{}\hlnum{0}\hlstd{}\hlsym{{]}{]}\ =\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;
}\\
175 \hlline{90\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{aux\
}\hlsym{=\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;
}\\
176 \hlline{91\
}\hlstd{\\
177 \hlline{92\
}}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{for\
}\hlstd{}\hlsym{(
}\hlstd{}\hlkwb{int\
}\hlstd{t\
}\hlsym{=\
}\hlstd{}\hlnum{1}\hlstd{}\hlsym{;\
}\hlstd{t\
}\hlsym{$<$\
}\hlstd{N
}\hlsym{;\
}\hlstd{t
}\hlsym{++)\ \
{}\\
178 \hlline{93\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{if\
}\hlstd{}\hlsym{(
}\hlstd{ahora
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{t
}\hlsym{{]}{]}\ ==\
}\hlstd{aux\
}\hlsym{\&\&\
}\hlstd{comparador
}\hlsym{.
}\hlstd{}\hlkwd{clave
}\hlstd{}\hlsym{(
}\hlstd{sa
}\hlsym{{[}}\hlstd{t
}\hlsym{{-
}}\hlstd{}\hlnum{1}\hlstd{}\hlsym{{]})\ ==\
}\hlstd{comparador
}\hlsym{.
}\hlstd{}\hlkwd{clave
}\hlstd{}\hlsym{(
}\hlstd{sa
}\hlsym{{[}}\hlstd{t
}\hlsym{{]}))\ \
{}\\
179 \hlline{94\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{proximo
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{t
}\hlsym{{]}{]}\ =\
}\hlstd{bucket
}\hlsym{;
}\\
180 \hlline{95\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{parar\
}\hlsym{=\
}\hlstd{}\hlkwa{false
}\hlstd{}\hlsym{;
}\\
181 \hlline{96\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}\
}\hlstd{}\hlkwa{else\
}\hlstd{}\hlsym{\
{}\\
182 \hlline{97\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{aux\
}\hlsym{=\
}\hlstd{ahora
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{t
}\hlsym{{]}{]};
}\\
183 \hlline{98\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{bucket\
}\hlsym{=\
}\hlstd{t
}\hlsym{;
}\\
184 \hlline{99\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{proximo
}\hlsym{{[}}\hlstd{sa
}\hlsym{{[}}\hlstd{t
}\hlsym{{]}{]}\ =\
}\hlstd{bucket
}\hlsym{;
}\\
185 \hlline{100\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
186 \hlline{101\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
187 \hlline{102\
}\hlstd{\\
188 \hlline{103\
}}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwd{swap
}\hlstd{}\hlsym{(
}\hlstd{ahora
}\hlsym{,\
}\hlstd{proximo
}\hlsym{);
}\\
189 \hlline{104\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{if\
}\hlstd{}\hlsym{(
}\hlstd{parar
}\hlsym{)\
}\hlstd{}\hlkwa{break
}\hlstd{}\hlsym{;
}\\
190 \hlline{105\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{parar\
}\hlsym{=\
}\hlstd{}\hlkwa{true
}\hlstd{}\hlsym{;
}\\
191 \hlline{106\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
192 \hlline{107\
}\hlstd{\\
193 \hlline{108\
}}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlslc{//\ LCP\ (Kasai)
}\\
194 \hlline{109\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{total\
}\hlsym{=\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;
}\\
195 \hlline{110\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlkwb{int\
}\hlstd{k\
}\hlsym{=\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;
}\\
196 \hlline{111\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{for\
}\hlstd{}\hlsym{(
}\hlstd{}\hlkwb{int\
}\hlstd{i\
}\hlsym{=\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;\
}\hlstd{i\
}\hlsym{$<$\
}\hlstd{N
}\hlsym{;\
}\hlstd{i
}\hlsym{++)\ \
{}\\
197 \hlline{112\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{if\
}\hlstd{}\hlsym{(
}\hlstd{k\
}\hlsym{$>$\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{)\ \
{}\\
198 \hlline{113\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{k
}\hlsym{{-
}{-
};
}\\
199 \hlline{114\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
200 \hlline{115\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{if\
}\hlstd{}\hlsym{(
}\hlstd{ahora
}\hlsym{{[}}\hlstd{i
}\hlsym{{]}\ ==\
}\hlstd{N
}\hlsym{{-
}}\hlstd{}\hlnum{1}\hlstd{}\hlsym{)\ \
{}\\
201 \hlline{116\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{total\
}\hlsym{+=\
}\hlstd{N\
}\hlsym{+\
}\hlstd{}\hlnum{1\
}\hlstd{}\hlsym{{-
}\
}\hlstd{sa
}\hlsym{{[}}\hlstd{N
}\hlsym{{-
}}\hlstd{}\hlnum{1}\hlstd{}\hlsym{{]};
}\\
202 \hlline{117\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{k\
}\hlsym{=\
}\hlstd{}\hlnum{0}\hlstd{}\hlsym{;
}\\
203 \hlline{118\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{continue
}\hlstd{}\hlsym{;
}\\
204 \hlline{119\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
205 \hlline{120\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwb{int\
}\hlstd{j\
}\hlsym{=\
}\hlstd{sa
}\hlsym{{[}}\hlstd{ahora
}\hlsym{{[}}\hlstd{i
}\hlsym{{]}+
}\hlstd{}\hlnum{1}\hlstd{}\hlsym{{]};
}\\
206 \hlline{121\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{}\hlkwa{while\
}\hlstd{}\hlsym{(
}\hlstd{text
}\hlsym{{[}}\hlstd{i
}\hlsym{+
}\hlstd{k
}\hlsym{{]}\ ==\
}\hlstd{text
}\hlsym{{[}}\hlstd{j
}\hlsym{+
}\hlstd{k
}\hlsym{{]})\
}\hlstd{k
}\hlsym{++;
}\\
207 \hlline{122\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \ \ \ \ \
}\hlstd{total\
}\hlsym{+=\
}\hlstd{N\
}\hlsym{{-
}\
}\hlstd{k\
}\hlsym{{-
}\
}\hlstd{sa
}\hlsym{{[}}\hlstd{ahora
}\hlsym{{[}}\hlstd{i
}\hlsym{{]}{]};
}\\
208 \hlline{123\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlsym{\
}}\\
209 \hlline{124\
}\hlstd{\\
210 \hlline{125\
}}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlslc{//\ El\ codigo\ de\ arriba\ pone\ un\
{-
}1\ en\ la
}\\
211 \hlline{126\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlslc{//\ fila\ final\ del\ LCP\ en\ lugar\ de\ un\
0\ en\ la\ primera,
}\\
212 \hlline{127\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlslc{//\ asi\ que\ hay\ que\ restarlo\ ahora.
}\\
213 \hlline{128\
}\hlstd{}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{total\
}\hlsym{=\
}\hlstd{total\
}\hlsym{{-
}\
}\hlstd{}\hlnum{1}\hlstd{}\hlsym{;
}\\
214 \hlline{129\
}\hlstd{\\
215 \hlline{130\
}}\hlstd{\ \ \ \ \ \ \ \
}\hlstd{}\hlkwd{printf
}\hlstd{}\hlsym{(
}\hlstd{}\hlstr{"\%lld
}\hlesc{$
\backslash$n
}\hlstr{"
}\hlstd{}\hlsym{,\
}\hlstd{total
}\hlsym{);
}\\
216 \hlline{131\
}\hlstd{}\hlstd{\ \ \ \
}\hlstd{}\hlsym{\
}}\\
217 \hlline{132\
}\hlstd{}\hlsym{\
}}\hlstd{}\\
223 La implementación es bastante directa a partir de lo expresado anteriormente. Se
224 reservan arreglos estáticos de memoria para mejorar la eficiencia del algoritmo, y se
225 utiliza la función de ordenamiento provista por la STL cuyo rendimiento es excelente.
227 Se utilizan dos arreglos para los
\textit{buckets
}, que se van intercambiando en $O(
1)$
228 mediante un
\textit{swap
} de punteros para ir modificando los valores en cada
229 pasada. El objeto comparador
\textit{Comparador
} se utiliza para realizar las comparaciones
230 entre los prefijos, utilizando como clave su número de
\textit{bucket
}. En la primera
231 pasada, se inicializan los números de
\textit{bucket
} con los valores de los caracteres en la cadena,
232 pero enseguida se sobreescriben esos valores con enteros entre $
0$ y $n-
1$. Esto evita
233 especializar el método de comparación para la primera pasada del programa.
235 Como era de esperarse, el invariante del ciclo principal es que al comenzar
236 el cuerpo del ciclo, están ordenados los sufijos si solo se tienen en cuenta
237 sus primeros $K$ caracteres.
239 El algoritmo de Kasai sigue la implementación convencional, y la suma
240 de los valores es la esperada.